#include "assert_helper.h"
#include "charset_convert.h"

namespace utility {

/*
 * 目标缓冲dst为null时返回转换后的字符个数（不含结束符'\0'）
 * 函数会处理结束符，即会自动加上结束符
 * */
size_t
UTF_8ToUnicode(TCHAR * dst, size_t dst_size/*bytes*/, const char * src)
{
	IF_NULL_RETURN_VALUE(src, CONVERT_ERROR);
	dst_size -= dst_size & 1 ? 1 : 0; // little-entain unicode 所占空间为2的倍数
	int c = 0;
	size_t	real_size = 0;
	size_t	len = 0;

	while (*src) {
		if (NULL == dst || real_size * sizeof(TCHAR) + sizeof(TCHAR) < dst_size) {
			c = 7;
			while (*src & (1 << c)) --c;
			switch (7 - c) {
				case 0:
					if (NULL != dst) {
						dst[real_size++] = *src++;
					} else {
						++src;
					}
				break;
				case 2:
					src += 2;
				break;
				case 3:
					if (NULL != dst) {
						dst[real_size]	= (src[0] & 0x1F) << 12;
						dst[real_size]	|= (src[1] & 0x3F) << 6;
						dst[real_size++] |= (src[2] & 0x3F);
					}
					src += 3;
				break;
				default:
					assert(false);
				break;
			}
		} else {			
			break;
		}
		++len;
	}
	if (NULL != dst) dst[real_size] = 0; // handle end of string
	return len;
}

/*
 * 目标缓冲dst为null时返回转换后的字符个数
 * */
size_t/*characters*/
UnicodeToUTF_8(char* dst, size_t dst_size/*bytes*/, const TCHAR * src)
{
    // 注意 WCHAR高低字的顺序,低字节在前，高字节在后
	IF_NULL_RETURN_VALUE(src, CONVERT_ERROR);

	size_t	len = 0;
	size_t	real_size = 0;
	while (*src) {
		if (NULL != dst) {
			if (real_size + 3 < dst_size) {
				if (0 == *(reinterpret_cast<const char *>(src) + 1)) {	// ASCII compatible utf-8
					dst[real_size++] = *(reinterpret_cast<const char *>(src));
				} else if (*((unsigned int *)src) < 2048) { // 2 bytes utf-8
					dst[real_size++] = (0xC0 | (*src >> 6));
					dst[real_size++] = (0x80 | (*src & 0x3F));
				} else { // 3 bytes utf-8
					dst[real_size++] = (0xE0 | (*src >> 12));
					dst[real_size++] = (0x80 | ((*src >> 6) & 0x3F));
					dst[real_size++] = (0x80 | (*src & 0x3F));
				}
			} else {
				break;
			}
		}
		++len;
		++src;
	}
	if (NULL != dst) dst[real_size] = '\0';
	return len;
}

void UnicodeToGB2312(char* pOut,TCHAR uData)
{
    //::WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(TCHAR),NULL,NULL);
    return;
}    

void Gb2312ToUnicode(TCHAR* pOut,char *gbBuffer)
{
    //::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1);
    return ;
}

void GB2312ToUTF_8(std::string & pOut,char *pText, int pLen)
{
/*    char buf[4];
    int nLength = pLen* 3;
    char* rst = new char[nLength];
   
    memset(buf,0,4);
    memset(rst,0,nLength);
   
    int i = 0;
    int j = 0;     
    while(i < pLen)
    {
            //如果是英文直接复制就可以
            if( *(pText + i) >= 0)
            {
                    rst[j++] = pText[i++];
            }
            else
            {
                    TCHAR pbuffer;
                    Gb2312ToUnicode(&pbuffer,pText+i);
                   
                    UnicodeToUTF_8(buf,&pbuffer);
                   
                    unsigned short int tmp = 0;
                    tmp = rst[j] = buf[0];
                    tmp = rst[j+1] = buf[1];
                    tmp = rst[j+2] = buf[2];   
                   
                    j += 3;
                    i += 2;
            }
    }
    rst[j] = '\0';

    //返回结果
    pOut = rst;            
    delete []rst;  
   
    return;*/
}

void UTF_8ToGB2312(std::string & pOut, char *pText, int pLen)
{
/*    char * newBuf = new char[pLen];
    char Ctemp[4];
    memset(Ctemp,0,4);

    int i =0;
    int j = 0;
   
    while(i < pLen)
    {
        if(pText > 0)
        {
                newBuf[j++] = pText[i++];                      
        }
        else                
        {
                TCHAR Wtemp;
                UTF_8ToUnicode(&Wtemp,pText + i);
       
                UnicodeToGB2312(Ctemp,Wtemp);
           
                newBuf[j] = Ctemp[0];
                newBuf[j + 1] = Ctemp[1];

                i += 3;   
                j += 2;  
        }
    }
    newBuf[j] = '\0';
   
    pOut = newBuf;
    delete []newBuf;
   
    return;*/
}

}
